from pattern.circuit import Control
import weakref, gobject
import os.path, posixpath, urllib
import BaseHTTPServer, SimpleHTTPServer


class SimpleHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):

    def get_root_path(self):
        s = self.server
        if s is not None and hasattr(s, 'getRootPath'):
            return s.getRootPath()
        else:
            return os.getcwd()

    def do_GET(self):
        s = self.server
        if s is not None and hasattr(s, 'notify'):
            s.notify(self.path)
        SimpleHTTPServer.SimpleHTTPRequestHandler.do_GET(self)

    def translate_path(self, path):
        """Translate a /-separated PATH to the local filename syntax.

        Components that mean special things to the local file system
        (e.g. drive or directory names) are ignored.  (XXX They should
        probably be diagnosed.)

        This method is overridden to allow starting from a path other than
        the current working directory, as is the behaviour of SimpleHTTPServer.
        """
        path = posixpath.normpath(urllib.unquote(path))
        words = path.split('/')
        words = filter(None, words)
        path = self.get_root_path()
        for word in words:
            drive, word = os.path.splitdrive(word)
            head, word = os.path.split(word)
            if word in (os.curdir, os.pardir): continue
            path = os.path.join(path, word)
        return path
        


class entry(Control):

    def realize(self, event):
        if not hasattr(event.shape, 'port'):
            event.shape.port = 8080
        self.port = event.shape.port
        self.realized = event
        self.initiate(event)

    def initiate(self, event):
        import thread
        self.server = BaseHTTPServer.HTTPServer(('', self.port),
                                                SimpleHTTPRequestHandler)
        shape = weakref.ref(event.shape)
        self.server.getRootPath = lambda: self().getRootPath(shape)
        self.server.notify = self.notify
        self = weakref.ref(self)
        onConnect = lambda source, condition: self().incomingConnection()
        self().watch = gobject.io_add_watch(self().server.socket,\
                                            gobject.IO_IN | gobject.IO_HUP,
                                            onConnect)
        del event

    def incomingConnection(self):
        self.server.handle_request()
        return True

    def shutdown(self, event):
        gobject.source_remove(self.watch)

    def getRootPath(self, shape):
        shape = shape()
        if shape is None:
            return os.getcwd()
        else:
            if not hasattr(shape, 'root'):
                shape.root = "/"
            return shape.root
            
    def notify(self, *args):
        bridge = self.acquireInterface(self.realized, "onGet")
        if bridge is not None:
            bridge.push(*args)
    
